//
//  KMTool.swift
//  KaMengApplication
//
//  Created by DUONIU_MAC on 2018/8/20.
//  Copyright © 2018年 DUONIU_MAC. All rights reserved.
//

import UIKit
import AFNetworking
import MJRefresh
import SVProgressHUD
import CryptoSwift
import SwiftyJSON
import CoreImage
import Accelerate

class KMTool: NSObject {

    /// app跳转返回用标识
    static let MyAppScheme = "com.dn.KaMengApplication"
    /// 获取Document目录
    static let docDir = NSSearchPathForDirectoriesInDomains(.documentDirectory,
                                                            .userDomainMask, true)[0]
    
    static let appdelegate = UIApplication.shared.delegate as? AppDelegate
    
    internal static var manager : AFHTTPSessionManager {
        
        ///设置网络请求超时时间
        let configuration = URLSessionConfiguration.default
        configuration.timeoutIntervalForRequest = 30
        
        let manager = AFHTTPSessionManager.init(sessionConfiguration: configuration)
        
        manager.responseSerializer.acceptableContentTypes = NSSet.init(objects: ["text/html","application/json","text/json","text/javascript"]) as? Set<String>
        
        
        return manager
    }
    
    // MARK: - 沙盒存储
    // MARK: 往沙盒添加数据
    static func setObject(_ value: Any?, forKey defaultName: String) {
        UserDefaults.standard.set(value, forKey: defaultName)
        UserDefaults.standard.synchronize()
    }
    
    static func setObject(_ value: Any?, forEnumKey defaultName: UDObject) {
        UserDefaults.standard.set(value, forKey: defaultName.rawValue)
        UserDefaults.standard.synchronize()
    }
    
    // MARK: 从沙盒取数据
    static func objectForKey(_ defaultName: String) -> Any?{
        return UserDefaults.standard.object(forKey: defaultName)
    }
    
    
    static func stringForKey(_ defaultName: String) -> String?{
        return UserDefaults.standard.string(forKey: defaultName)
    }
    
    static func stringForEnumKey(_ defaultName: UDObject) -> String?{
        return UserDefaults.standard.string(forKey: defaultName.rawValue)
    }
    
    static func boolForEnumKey(_ defaultName: UDObject) -> Bool?{
        return UserDefaults.standard.bool(forKey: defaultName.rawValue)
    }
    
    static func arrayForKey(_ defaultName: String) -> [Any]?{
        return UserDefaults.standard.array(forKey: defaultName)
    }
    
    static func arrayForEnumKey(_ defaultName: UDObject) -> [Any]?{
        //数组类型的key一般后加用户id
        return UserDefaults.standard.array(forKey: defaultName.rawValue)
    }
    
    static func stringArrayForEnumKey(_ defaultName:UDObject) -> [String]? {
        return UserDefaults.standard.stringArray(forKey: defaultName.rawValue)
    }
    
    static func dictionaryForKey(_ defaultName: String) -> [String : Any]?{
        return UserDefaults.standard.dictionary(forKey: defaultName)
    }
    
    static func dictionaryForEnumKey(_ defaultName: UDObject) -> [String : Any]?{
        return UserDefaults.standard.dictionary(forKey: defaultName.rawValue)
    }
    
    static func dataForKey(_ defaultName: String) -> Data?{
        return UserDefaults.standard.data(forKey: defaultName)
    }
    
    static func dataForEnumKey(_ defaultName: UDObject) -> Data?{
        return UserDefaults.standard.data(forKey: defaultName.rawValue)
    }
    
    static func removeObjectForKey(_ defaultName: String){
        UserDefaults.standard.removeObject(forKey: defaultName)
        UserDefaults.standard.synchronize()
    }
    
    static func removeObjectForEnumKey(_ defaultName: UDObject){
        UserDefaults.standard.removeObject(forKey: defaultName.rawValue)
        UserDefaults.standard.synchronize()
    }
    
    
    // MARK: - 提醒操作
    // MARK: 只有一个按钮的提醒操作
    /// 只有一个按钮的提醒操作
    ///
    /// - Parameters:
    ///   - title: 标题
    ///   - msg: 提示信息
    ///   - target: 显示在哪个控制器上
    ///   - actionTitle: 动作按钮标题
    ///   - cancelTitle: 取消按钮标题
    ///   - haveCancel: 是否有取消按钮
    ///   - handler: 点击确定后的操作
    @objc static func setAlertView(title:String? = global_systemAlert,msg:String? , target:UIViewController? ,actionTitle:String? = global_confirm,cancelTitle:String? = global_cancel,haveCancel:Bool , handler:((UIAlertAction) -> Void)?) {
        let alertView = UIAlertController.init(title: title, message: msg, preferredStyle: .alert)
        
        let enterAction = UIAlertAction.init(title: actionTitle, style: .default) { (alertView) in
            handler?(alertView)
        }
        
        if haveCancel {
            let cancelAction = UIAlertAction.init(title: cancelTitle, style: .cancel, handler: nil)
            alertView.addAction(cancelAction)
        }
        alertView.addAction(enterAction)
        target?.present(alertView, animated: true, completion: nil)
        
    }
    
    // MARK: - 提醒操作
    /// - Parameters:
    ///   - title: 标题
    ///   - msg: 提示信息
    ///   - target: 显示在哪个控制器上
    ///   - actionTitle: 动作按钮标题
    ///   - cancelTitle: 取消按钮标题
    ///   - handler: 点击确定后的操作
    @objc static func setBottomAlertView(title:String? = global_systemAlert,msg:String? , target:UIViewController? ,actionTitle:[String],cancelTitle:String? = global_cancel,handler:((UIAlertAction) -> Void)?) {
        
        let alertView = UIAlertController.init(title: title, message: msg, preferredStyle: .actionSheet)
        
        for i in 0..<actionTitle.count {
            
            let action = UIAlertAction.init(title: actionTitle[i], style: .default) { (alert) in
                handler?(alert)
            }
            
            alertView.addAction(action)
        }
        
        
        let cancelAction = UIAlertAction.init(title: global_cancel, style: .cancel) { (alert) in
            
            handler?(alert)
        }
        
        alertView.addAction(cancelAction)
        
        target?.present(alertView, animated: true, completion: nil)
    }
    
    
    
    // MARK: - 设置刷新
    static func setRefresh(with scrollView :UIScrollView ,headerAction : (()->Void)? , footerAction : (()->Void)? ) {
        
        //下拉刷新
        let header = MJRefreshNormalHeader.init(refreshingBlock: headerAction)
        scrollView.mj_header = header
        
        header?.activityIndicatorViewStyle = .gray
        header?.stateLabel.textColor = .gray
        
        
        if footerAction == nil {
            return
        }
        
        //上拉加载
        let footer =  MJRefreshBackNormalFooter.init(refreshingBlock: footerAction)
        scrollView.mj_footer = footer
        
        footer?.activityIndicatorViewStyle = .gray
        footer?.stateLabel.textColor = .gray
        
    }
    
    //MARK: - 获取当前屏幕顶层显示控制器
    /// 获取当前屏幕顶层显示控制器
    ///
    /// - Returns: viewController
    static func currentViewController() -> UIViewController?{
        let keyWindow = UIApplication.shared.keyWindow
        var currentVc = keyWindow?.rootViewController
        if currentVc?.presentedViewController != nil {
            currentVc = currentVc?.presentedViewController
        }
        if let vc = currentVc as? UINavigationController {
            currentVc = vc.visibleViewController
        }else if let vc = currentVc as? UITabBarController {
            currentVc = vc.selectedViewController
        }
        
        return currentVc
    }
    
    //MARK: 自定义弹框
    static func showText(_text:String) {
        
        let windwow = UIApplication.shared.keyWindow
        let showView = UIView()
        showView.backgroundColor = UIColor.black
        showView.frame = CGRect.init(x: 1, y: 1, width: 1, height: 1)
        
        showView.layer.cornerRadius = 5.0
        showView.layer.masksToBounds = true
        windwow?.addSubview(showView)
        
        let label = UILabel()
        let size = _text.size(font: RATIO(maxNum: 14), width: RATIO(maxNum: 300))
        label.frame = .init(x: 0, y: 0, width: size.width, height: size.height)
        label.text = _text
        label.textColor = UIColor.white
        label.textAlignment = .center
        label.backgroundColor = UIColor.clear
        label.font = UIFont.systemFont(ofSize: RATIO(maxNum: 14))
        label.numberOfLines = 0
        
        showView.addSubview(label)
        
        showView.frame = .init(x: (ScreenW-size.width)/2, y: ScreenH - size.height - 20, width: size.width, height: size.height)
        
        UIView.animate(withDuration: 0.2, delay: 1, options: .curveLinear, animations: {
            
            showView.alpha = 0
            
        }) { (true) in
            
            showView.removeFromSuperview()
        }
      
    
        
    }
    
    
    // MARK: - 蒙版加载工具
    /// 显示加载动画
    ///
    /// - Parameter text: 加载文字提示
    static func waiting(_ text:String = loading) {
        SVProgressHUD.show(withStatus: text + "...")
        SVProgressHUD.setDefaultMaskType(.black)
    }
    
    /// 停止加载动画
    static func stop() {
        SVProgressHUD.dismiss()
    }
    
    // MARK: - 网络请求
    /// 网络请求
    ///
    /// - Parameters:
    ///   - method: 请求方式
    ///   - URLString: url
    ///   - parameters: 参数
    ///   - isBackground: 是否后台执行
    ///   - success: 请求成功回调
    ///   - failure: 请求失败回调
    static func requestMethod(_ method:RequestMethod, URLString:String , parameters : [String:Any]?,isBackground:Bool = false ,progress:((Progress) -> Swift.Void)? = nil,constructingBodyWith block: ((AFMultipartFormData) -> Swift.Void)? = nil, success :(([String:Any] , JSON) -> Void)? ,failure:(() -> Void)? ) {
        MyLog(parameters)
        MyLog(manager.requestSerializer.httpRequestHeaders)
        requestMethod(method,URLString:URLString, parameters: parameters,progress:progress,constructingBodyWith:block ,success: { (response, responseObject) in
            MyLog(response)
            MyLog(responseObject)

            if let value = responseObject as? [String:Any] {
                MyLog(value)
                let json = JSON.init(value)
                success?(value ,json)
            }else {
                if !isBackground {currentViewController()?.showErrorAlert()}
                failure?()
            }
            
            
        }) { (task, error) in
            MyLog(task?.response)
            MyLog("网络请求失败")
            let aError = error as NSError
            MyLog("Error : \(aError)")
            failure?()
            if isBackground {
                return
            }
            switch aError.code {
            case -1009 :
                currentViewController()?.showErrorAlert(title: global_networkError)
            case -1001 :
                currentViewController()?.showErrorAlert(title: global_networkTimedOut)
            default:
                currentViewController()?.showErrorAlert(msg:aError.localizedDescription)
                break
            }
            
        }
        
    }
    // MARK: 网络请求(私有方法)
    fileprivate static func requestMethod(_ method:RequestMethod, URLString:String , parameters : [String:Any]? ,progress:((Progress) -> Swift.Void)?,constructingBodyWith block: ((AFMultipartFormData) -> Swift.Void)?, success :((URLResponse?, Any?) -> Void)? ,failure:((URLSessionDataTask?,Error) -> Void)? ) {
        
        switch method {
        case .post:
            manager.post(URLString, parameters: parameters, progress: progress, success: { (task, responseObject) in
                success?(task.response,responseObject)
            }, failure: { (task, aError) in
                failure?(task,aError)
            })
        case .get:
            manager.get(URLString, parameters: parameters, progress: progress, success: { (task, responseObject) in
                success?(task.response,responseObject)
            }, failure: { (task, aError) in
                failure?(task,aError)
            })
            
        case .upload:
            let request = AFHTTPRequestSerializer().multipartFormRequest(withMethod: "POST", urlString: URLString, parameters: parameters, constructingBodyWith: block, error: nil)
            let uploadTask = self.manager.uploadTask(withStreamedRequest: request as URLRequest, progress: {
                (uploadProgress) in
                progress?(uploadProgress)
            }) { (response, object, error) in
                
                if object != nil {
                    success?(response,object)
                }
                if error != nil {
                    failure?(nil,error!)
                }
                
            }
            uploadTask.resume()
        }
        
    }
    
    //MARK: 非json数据请求
    static func requestData(URLString:String , parameters : [String:Any]? ,progress:((Progress) -> Swift.Void)? = nil, success :((String) -> Void)?) {
        
        let configuration = URLSessionConfiguration.default
        configuration.timeoutIntervalForRequest = 30
        
        let manager = AFHTTPSessionManager.init(sessionConfiguration: configuration)
        
        manager.responseSerializer = AFHTTPResponseSerializer()
        manager.post(URLString, parameters: parameters, progress: progress, success: { (task, json) in
            
            //数据解析
            let string = NSString.init(data: json as! Data, encoding: String.Encoding.utf8.rawValue)
            MyLog(string)
            success?(string! as String)
            
            
        }) { (task, error) in
            KMTool.stop()
            MyLog(error.localizedDescription)
            
        }
    }
    
    //MARK: 非json数据Get请求
    static func requestGetData(URLString:String , parameters : [String:Any]? ,progress:((Progress) -> Swift.Void)? = nil, success :((Data) -> Void)?) {
        
        let configuration = URLSessionConfiguration.default
        configuration.timeoutIntervalForRequest = 30
        
        let manager = AFHTTPSessionManager.init(sessionConfiguration: configuration)
        
        manager.responseSerializer = AFHTTPResponseSerializer()
        manager.get(URLString, parameters: parameters, progress: progress, success: { (task, json) in
            
            //数据解析
            let string = NSString.init(data: json as! Data, encoding: String.Encoding.utf8.rawValue)
            MyLog(string)
            success?(json as! Data)
            
            
        }) { (task, error) in
            KMTool.stop()
            MyLog(error.localizedDescription)
            
        }
    }
    
    //MARK: 非json数据Post请求
    static func requestPostData(URLString:String , parameters : [String:Any]? ,progress:((Progress) -> Swift.Void)? = nil, success :((Data) -> Void)?) {
        
        let configuration = URLSessionConfiguration.default
        configuration.timeoutIntervalForRequest = 30
        
        let manager = AFHTTPSessionManager.init(sessionConfiguration: configuration)
        
        manager.responseSerializer = AFHTTPResponseSerializer()
        manager.post(URLString, parameters: parameters, progress: progress, success: { (task, json) in
            
            //数据解析
            let string = NSString.init(data: json as! Data, encoding: String.Encoding.utf8.rawValue)
            MyLog(string)
            success?(json as! Data)
            
            
        }) { (task, error) in
            KMTool.stop()
            MyLog(error.localizedDescription)
            
        }
    }
    
    //MARK: 获取用户资料
    static func getUserNews(userName : String,success:(()->Void)?) {
        
        KMTool.waiting()
        KMTool.requestMethod(.post, URLString: url_getUserNews, parameters: ["user_name":userName], success: { (value, json) in
            KMTool.stop()
            
            if json["status"].stringValue == "0" {
                
                if let user_nicename = json["user_nicename"].string {
                    KMTool.setObject(user_nicename, forEnumKey: .userName)
                }
                
                if let img = json["img"].string {
                    KMTool.setObject(img, forEnumKey: .avatar)
                }
                
                
                KMTool.setObject(true, forEnumKey: .isSignIn)
                success?()
            }else{
                KMTool.showText(_text: failToGetUserNews)
            }
            
        }) {
            KMTool.stop()
        }
        
    }
    
    //MARK: base64字符串转图片
    static func base64ToImage(base : String) -> UIImage {
        
        if base == "" {
            return UIImage()
        }
        
        let imageData = Data.init(base64Encoded: base)
        let image = UIImage.init(data: imageData!)
        
        return image!
    }
    
    //MARK: 图片转base64
    static func imageToBase64(image : UIImage) -> String {
        
        let imageData = UIImagePNGRepresentation(image)
        
        let imageBase64String = imageData?.base64EncodedString()
        
        return imageBase64String!
        
    }
    
    //MARK: 是否登录
    static func isSignIn() -> Bool {
        
        return KMTool.boolForEnumKey(.isSignIn)!
    }
    
    //MARK: 清空用户信息
    static func clearUserNews() {
        KMTool.setObject(false, forEnumKey: .isSignIn)
        KMTool.removeObjectForEnumKey(.userName)
        KMTool.removeObjectForEnumKey(.avatar)
        KMTool.removeObjectForEnumKey(.phone)
        
    }
    
    //MARK: 图片模糊
    static func blurryImage(image:UIImage) -> UIImage {
        
        let context = CIContext.init(options: nil)
        let ciImage = CIImage.init(cgImage: image.cgImage!)
        let filter = CIFilter.init(name: "CIGaussianBlur")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        //设置模糊程度
        filter?.setValue("5", forKey: "inputRadius")
        let result = filter?.value(forKey: kCIOutputImageKey)
        let outImage = context.createCGImage(result as! CIImage, from: ciImage.extent)
        let blurImage = UIImage.init(cgImage: outImage!)

        return blurImage
        
    }
    
    
    
    
    
}
